home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 May: Tool Chest / Dev.CD May 98 TC.toast / Tool Chest / Development Kits / HyperCard Related / APDA HyperCard Toolkits / HyperCard Serial Toolkit 2.6 / Source Code / sendSPortBytes.p < prev    next >
Encoding:
Text File  |  1995-02-07  |  5.4 KB  |  183 lines  |  [TEXT/MPS ]

  1. (*
  2.     sendSPortBytes byteList -- Send a series of bytes to the port. Interpret the parameter as a byte
  3.         list, one byte per item. Do the same translations as sendSPort does.
  4.  
  5.     To compile and link this file using Macintosh Programmer's Workshop,
  6.  
  7.         pascal -w sendSPortBytes.p
  8.         link -m ENTRYPOINT -o HyperCommands -rt XCMD=7037 -sn Main=sendSPortBytes ∂
  9.             sendSPortBytes.p.o "{MPW}"Libraries:interface.o "{MPW}"Libraries:Libraries:HyperXLib.o
  10.  
  11.     © Copyright 1989 by Apple Computer, Inc.
  12.  
  13.     Initial coding 12/89 by Harry R. Chesley.
  14. *)
  15.  
  16. {$R-}
  17.  
  18. {$S sendSPortBytes }     { Segment name must be the same as the command name. }
  19.  
  20. unit DummyUnit;
  21.  
  22. interface
  23.  
  24. uses MemTypes, QuickDraw, OSIntf, HyperXCmd;
  25.  
  26. procedure EntryPoint(paramPtr: XCmdPtr);
  27.     
  28. implementation
  29.  
  30. const
  31.  
  32. return = 13;                { Carriage return. }
  33. linefeed = 10;            { Line feed. }
  34. space = ord(' ');        { Space. }
  35. comma = ord(',');        { Comma. }
  36. zero = ord('0');        { Zero. }
  37. nine = ord('9');            { Nine. }
  38. lowera = ord('a');        { Lower-case a. }
  39. lowerf = ord('f');        { Lower-case f. }
  40. upperA = ord('A');    { Upper-case A. }
  41. upperF = ord('F');        { Upper-case F. }
  42.  
  43. procedure sendSPortBytes(paramPtr: XCmdPtr); forward;
  44.  
  45. procedure EntryPoint(paramPtr: XCmdPtr);
  46.  
  47.     begin
  48.         sendSPortBytes(paramPtr);
  49.     end;
  50.  
  51. procedure sendSPortBytes(paramPtr: XCmdPtr);
  52.  
  53.     var io: ParmBlkPtr;
  54.         col: integer;
  55.  
  56.     procedure Fail(errMsg: Str255); { set theResult and quit }
  57.         begin
  58.             paramPtr^.returnValue := PasToZero(paramPtr,errMsg);
  59.             exit(sendSPortBytes);
  60.         end;
  61.  
  62.     {$I SPortUtil.inc}
  63.  
  64.     function copyAndCount(copyFrom, copyTo: Ptr; var col: integer; doTheCopy: boolean): longInt;
  65.         { Copy and translate bytes from the source string to the destination, counting the size of the destination
  66.             as we go. If doTheCopy is not true, then don't actually do the copy, just accumulate the count. It assumes
  67.             that we're starting in the column indicated by col, and returns the new column in col. }
  68.  
  69.         var fromPtr, toPtr, nextFromPtr: Ptr;
  70.             nextCol: integer;
  71.             base, tot: integer;
  72.             theChar: SignedByte;
  73.  
  74.         procedure copyOne(d: SignedByte);
  75.  
  76.             begin
  77.                 if doTheCopy then toPtr^ := d;
  78.                 toPtr := pointer(ord4(toPtr)+1);
  79.                 col := col+1;
  80.             end;
  81.  
  82.         procedure copyCRLF;
  83.  
  84.             begin
  85.                 copyOne(return);
  86.                 if ThisSPort.sendLFs then copyOne(linefeed);
  87.                 col := 1;
  88.             end;
  89.  
  90.         begin
  91.         { Cycle thru all the bytes to be copied. }
  92.         fromPtr := copyFrom; toPtr := copyTo;
  93.         while fromPtr^ <> 0 do
  94.             begin
  95.                 { Get the next byte. }
  96.                 base := 10;
  97.                 tot := 0;
  98.                 if fromPtr^ = ord('$') then
  99.                     begin
  100.                         base := 16;
  101.                         while not (fromPtr^ in [0,zero..nine,lowera..lowerf,upperA..upperF,comma]) do
  102.                             fromPtr := pointer(ord4(fromPtr)+1);
  103.                     end;
  104.                 while fromPtr^ in [zero..nine,lowera..lowerf,upperA..upperF] do
  105.                     begin
  106.                         theChar := fromPtr^;
  107.                         if theChar in [zero..nine] then tot := base*tot + theChar - zero
  108.                         else if theChar in [lowera..lowerf] then tot := base*tot + theChar - lowera + 10
  109.                         else tot := base*tot + theChar - upperA + 10;
  110.                         fromPtr := pointer(ord4(fromPtr)+1);
  111.                     end;
  112.                 theChar := SignedByte(tot);
  113.                 while not (fromPtr^ in [0,comma]) do fromPtr := pointer(ord4(fromPtr)+1);
  114.                 if fromPtr^ <> 0 then fromPtr := pointer(ord4(fromPtr)+1);
  115.                 while not (fromPtr^ in [0,zero..nine,lowera..lowerf,upperA..upperF,comma]) do
  116.                     fromPtr := pointer(ord4(fromPtr)+1);
  117.  
  118.                 { Check if it was a return. }
  119.                 if theChar = return then copyCRLF
  120.                 { Otherwise, check for auto-wrap on space. }
  121.                 else if ThisSPort.autoWrap and (theChar = space) and (col <= WRAPCOLUMN) then
  122.                     begin
  123.                         { Send the space. }
  124.                         copyOne(space);
  125.                         { This was a space, so we may want to auto-wrap here. Find out where the next auto-wrap
  126.                             would occur. }
  127.                         nextFromPtr := fromPtr;
  128.                         nextCol := col;
  129.                         while (nextFromPtr^ <> return) and (nextFromPtr^ <> space) and (nextFromPtr^ <> 0) do
  130.                             begin
  131.                                 nextFromPtr := pointer(ord4(nextFromPtr)+1);
  132.                                 nextCol := nextCol+1;
  133.                             end;
  134.                         { If the next auto-wrap is past the wrap column, then auto-wrap here. }
  135.                         if (nextCol > WRAPCOLUMN) and (fromPtr^ <> return) and (fromPtr^ <> 0) then copyCRLF;
  136.                     end
  137.                 { Otherwise, check for a forced auto-wrap (one word larger than a line). }
  138.                 else if ThisSPort.autoWrap and (col >= WRAPCOLUMN) then
  139.                     begin
  140.                         if col = WRAPCOLUMN then copyOne(space);
  141.                         copyCRLF;
  142.                         copyOne(theChar);
  143.                     end
  144.                 else copyOne(theChar);
  145.             end;
  146.  
  147.             { Compute the final size of the output. }
  148.             copyAndCount := ord4(toPtr) - ord4(copyTo);
  149.         end;
  150.  
  151.     begin
  152.         if paramPtr^.paramCount <> 1 then Fail('parameter count is not 1');
  153.  
  154.         SetUpSPortGlobals;
  155.         EnsureOpenPort;
  156.  
  157.         { Check for an empty string being sent. }
  158.         if paramPtr^.params[1] = nil then exit(sendSPortBytes);
  159.         if paramPtr^.params[1]^^ = 0 then exit(sendSPortBytes);
  160.  
  161.         { Get an I/O block. }
  162.         io := WaitForFreeIOBlk;
  163.  
  164.         { Get rid of the old buffer, if any. }
  165.         if io^.ioBuffer <> nil then DisposPtr(io^.ioBuffer);
  166.         { Figure out the size of the new buffer and allocate it. }
  167.         col := ThisSPort.currentColumn;
  168.         io^.ioBuffer := NewPtr(copyAndCount(paramPtr^.params[1]^,nil,col,false));
  169.         if io^.ioBuffer = nil then Fail('could not allocate buffer');
  170.  
  171.         { Copy the data into the buffer, and set the output request size. }
  172.         col := ThisSPort.currentColumn;
  173.         io^.ioReqCount := copyAndCount(paramPtr^.params[1]^,io^.ioBuffer,col,true);
  174.  
  175.         { Send the data to the port asynchronously. }
  176.         if PBWrite(io,true) <> noErr then Fail('PBWrite failed');
  177.  
  178.         { Remember the column. }
  179.         Globals^^.ports[Globals^^.selectedPort].currentColumn := col;
  180.     end;
  181.  
  182. end.
  183.